<?php

    //modeaccess field of formdescriptior indicates what mode a module shows up in.
    //3 digit binary number
    //4->100 Admin
    //2->010 Site
    //1->001 Intranet
    //Intranet, Site and Admin Permissions (Temporary)
   
	define("PERMISSION_INTRANET", 1); // 001
	define("PERMISSION_SITE", 2);	  // 010
	define("PERMISSION_ADMIN", 4);	  // 100
	define("PERMISSION_MAILOUT", 8);


	
	//these are not OCTAL !!! i would use base 4 then it would be easy peasy .. but what speaks base4

	define("PERMISSION_VIEW",	1);	// 000000001
	define("PERMISSION_EDIT",	2);	// 000000010
	define("PERMISSION_ADD",	4);	// 000000100
	define("PERMISSION_DELETE",	8);	// 000001000
	define("PERMISSION_PRIV",	16); //000010000 // if a user is allowed to modify the permissions of the particular document
	
	define("PERMISSION_ALL",	0);
	define("PERMISSION_GROUP",	5);
	define("PERMISSION_USER",	PERMISSION_GROUP << 1);

	//user	group	all
	//pdaev	pdaev	pdaev
	//00000	01000	00111
	
	//1			4			8
	//ALL	->	GROUP	->	USER
	
	//does the user have permission to add a document of this type
	function addFormAuth($userInfo, $formDescription, $documentCode = NULL, &$db){
		return formAuth(PERMISSION_ADD,$userInfo,$formDescription, $documentCode, $db);
	}
	
	//does  the user have permission to edit the document
	/**
	* @desc Authenticates user for editing specified form
	*/
	function editFormAuth($userInfo, $formDescription, $documentCode = NULL, &$db){
		return formAuth(PERMISSION_EDIT,$userInfo,$formDescription, $documentCode, $db);
	}
	
	//does the user have permission to view the document
	function viewFormAuth($userInfo, $formDescription, $documentCode = NULL, &$db){
		//you can also view a document type if you are allowed 
		// to edit it.. but not vise versa
		return formAuth(PERMISSION_VIEW,$userInfo,$formDescription, $documentCode, $db) 
		|| formAuth(PERMISSION_EDIT, $userInfo,$formDescription, $documentCode, $db);
	}
	
	//does the user have permission to delete the document
	function deleteFormAuth($userInfo, $formDescription, $documentCode = NULL, &$db){
		return formAuth(PERMISSION_DELETE,$userInfo,$formDescription, $documentCode, $db);
	}
	//does the user have permission for altering privileges.. of the document.. not the form???
	function permissionFormAuth($userInfo, $formDescription, $documentCode = NULL, &$db){
		return formAuth(PERMISSION_PRIV,$userInfo,$formDescription, $documentCode, $db);
	}
	
	//general function for working out for permissions etc.
	function formAuth($permission, $userInfo, $formDescription, $documentCode, &$db){		
		
		
		// we need to add a site check in here also.. 
		// for permissions..
		
		//is a root user.
		if ( $userInfo->usertype == CMS_USERTYPE_SU ) {
			return true;
		}
		
		//This is for the default form permissions
		$permissionMask = null;
		switch($permission){
			//if we have specified a valid permission.. then we 
			//wont break
			case PERMISSION_ADD:
			case PERMISSION_EDIT:
			case PERMISSION_VIEW:
			case PERMISSION_DELETE:
			case PERMISSION_PRIV:
				$permissionMask = $permission;
			break;
				
			default:
				return false;
		}
		
		$permissionMask = $permission;
		//this is god awful here... remove me i think
		//global $db;
		
		//First we check for permissions for the and individual record if these are false then we check the formdescriptor.
		if($documentCode != null) {
			$tableWriter = new CmsTableWriter(CMS_FORMAT,$db);
			$document = $tableWriter->readItem($documentCode);
		}
		
		//uid permissions
		$uid = $formDescription->uid;
		if($documentCode != null && $document->uid > 0 && $document->permissions != '' && $document->permissions > 0 ) {
			$uid = $document->uid;
		}
		
		if ($uid > 0 && $userInfo->uid == $uid && $document->permissions != '' && $document->permissions > 0) {	
			$permissionMask = $permissionMask | ( $permission << PERMISSION_USER ) ;
		}
		
		//gid perms
		$gids = groupsForUserId($userInfo->uid, $db);

		//find the groups..
		$groupId = $formDescription->gid;
		if($documentCode != null && $document->gid > 0 && $document->permissions != '' && $document->permissions > 0) {
			$groupId = $document->gid;
		}
		if ($groupId > 0) {
			//print("(G)");	
			foreach ($gids as $key => $gid) {
				if ( $gid === $groupId ) {
					$permissionMask = $permissionMask | ( $permission << PERMISSION_GROUP);
					break;
				}
			}
		}
		
		if($documentCode != null && $document->permissions != '' && $document->permissions > 0 && $document->permissions != null) {
			return  $document->permissions & $permissionMask;
		} else {
			return  $formDescription->permission & $permissionMask;
		}
		
	}
	
	//takes a user id..
	
	function groupObjectsForUserId($uid, &$db) {
 		return $db->getAllAsObjects("SELECT t1.* FROM grouplist AS t1,usergroup AS t2 WHERE t1.gid = t2.gid AND t2.uid=?", ($a = array($uid)) );	
	}
		
	function groupsForUserId($uid, &$db) {
		$groups =  groupObjectsForUserId($uid,$db);
		$modes = array();
		foreach($groups as $group){
			array_push($modes, $group->gid);
		}
		return $modes;
	}

	function modesForUserId($uid, &$db){
		$groups =  groupObjectsForUserId($uid,$db);
		$modes = array();
		//there must be a quicker way of filtering an array.
		foreach($groups as $group){
			if (($group->enablemode & 1) && $group->modemask)	
				array_push($modes, $group);
		}
		return $modes;
	}
	
	function usersForGroup($gid, &$db) {
		return $db->getAllAsArray("SELECT uid FROM usergroup WHERE gid =?", ($a = array($gid)));
	}
	

	function groupObjectForMode($mode, &$db){
		$db->prepareAndExecuteQuery("SELECT * FROM grouplist WHERE modemask=? LIMIT 1", ($a = array($mode)) );
		return $db->nextObject();
	}
	
	function groupForMode($mode, &$db){
		$group = groupObjectForMode($mode, $db);
		if (is_null($group)){
			return 0;
		} else {
			return $group->gid;
		}
		
	}
	
	function permissionForMode($uid, $mode, &$db){
		$userModes = modesForUserId($uid, $db);
		$userModeMasks = array_map("modemaskmap",$userModes);
		return in_array($mode, $userModeMasks);
	}
	
	function modemaskmap($n){
		if (key_exists('modemask',$n)){
			return $n->modemask;
		}
		return null;
	}
	
	function getGroupIdFromModeCode($string, &$db){
		$q = "SELECT gid FROM grouplist WHERE modecode='" . $string ."'";
		$db->prepareAndExecuteQuery($q);
		if (($o = $db->nextObject())){
			return $o->gid;
		} else {
			return  "4";
		}
	}

	function getSiteModesForUser($uid,&$db){
		$sites =  groupObjectsForUserId($uid,$db);
		$siteModes = array();
		foreach($sites as $site){
			if (($site->enablemode & 2) && $site->modemask)	
				array_push($siteModes, $site);
		}
		return $siteModes;
	}
	
	function checkSMSListPermissions($db, $listid = null, $uid = null) {
		$userTableWriter = new CmsTableWriter("user", $db);
		$userTableWriter->resetCustomIterator(" WHERE uid='".$uid."'");
		if ($row = $userTableWriter->nextItem()) {
			if ($row->usertype == 0) {
				return true;
			}
		}
		
		$gids = array();
		$db->executeQuery("SELECT gid FROM usergroup WHERE uid='".$uid."' GROUP BY gid");
		
		while ($row = $db->nextRow()) {
			$gids[] = $row[0];
		}
		
		$listGroupsTableWriter = new CmsTableWriter("smslist_cms_listgroups", $db);
		$listUsersTableWriter = new CmsTableWriter("smslist_cms_listusers", $db);
		
		$listGroupsTableWriter->resetCustomIterator(" WHERE listid='".$listid."' AND gid IN (".implode(", ",$gids).")");
		if ($listGroupsTableWriter->nextItem()) {
			return true;
		}
		else {
			$listUsersTableWriter->resetCustomIterator(" WHERE list='".$listid."' AND uid='".$uid."'");
			if ($listUsersTableWriter->nextItem()) {
				return true;
			}
		}
		return false;
	}
	
	function checkMailListPermissions($db, $listid = null, $uid = null) {
		$userTableWriter = new CmsTableWriter("user", $db);
		$userTableWriter->resetCustomIterator(" WHERE uid='".$uid."'");
		if ($row = $userTableWriter->nextItem()) {
			if ($row->usertype == 0) {
				return true;
			}
		}
		$gids = array();
		$db->executeQuery("SELECT gid FROM usergroup WHERE uid='".$uid."' GROUP BY gid");
		while ($row = $db->nextRow()) {
			$gids[] = $row[0];
		}
		$listGroupsTableWriter = new CmsTableWriter("listgroups", $db);
		$listUsersTableWriter = new CmsTableWriter("listusers", $db);
		$listGroupsTableWriter->resetCustomIterator(" WHERE listid='".$listid."' AND gid IN (".implode(",",$gids).")");
		if ($listGroupsTableWriter->nextItem()) {
			return true;
		}
		else {
			$listUsersTableWriter->resetCustomIterator(" WHERE listid='".$listid."' AND uid='".$uid."'");
			if ($listUsersTableWriter->nextItem()) {
				return true;
			}
		}
		return false;
	}
	
?>